home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / demos / OpenGL / stonehenge / scene.c++ < prev    next >
C/C++ Source or Header  |  1996-11-11  |  19KB  |  805 lines

  1. /*
  2.  * (c) Copyright 1993, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software for
  6.  * any purpose and without fee is hereby granted, provided that the above
  7.  * copyright notice appear in all copies and that both the copyright notice
  8.  * and this permission notice appear in supporting documentation, and that
  9.  * the name of Silicon Graphics, Inc. not be used in advertising
  10.  * or publicity pertaining to distribution of the software without specific,
  11.  * written prior permission.
  12.  *
  13.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  14.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  15.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  16.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  17.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  18.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  19.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  20.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  21.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  22.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  23.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  24.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  25.  *
  26.  * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND
  27.  * Use, duplication, or disclosure by the Government is subject to
  28.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  29.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  30.  * clause at DFARS 252.227-7013 and/or in similar or successor
  31.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  32.  * Unpublished-- rights reserved under the copyright laws of the
  33.  * United States.  Contractor/manufacturer is Silicon Graphics,
  34.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  35.  *
  36.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  37.  */
  38. #include <stdlib.h>
  39. #include <stdio.h>
  40.  
  41. #include <GL/glu.h>
  42. #include <GL/glx.h>
  43. #include "rgb.h"
  44. #include "Point.h"
  45. #include "Ring.h"
  46. #include "Roundwall.h"
  47. #include "Ellipse.h"
  48. #include "Telescope.h"
  49.  
  50. #define SCENE_EXTERN
  51. #include "scene.h"
  52.  
  53. GLfloat mat_view[16];
  54. GLfloat view_rotx = 0;
  55. GLfloat fov = 45.0, aspect = 1.0;
  56. static Point eyep = {0, 0, .5};
  57. static Point lookp = {0, 1, .25};
  58.  
  59. TimeDate current_time;
  60.  
  61. static int list_ground;
  62. static int list_texture_ground;
  63. static int list_trees;
  64. static int list_texture_trees;
  65. static int list_ring;
  66. static int list_ellipse;
  67. static int list_texture_stones;
  68. static int list_shadows;
  69. static int list_telescope;
  70. static int list_texture_telescope;
  71. int draw_ground = 1;
  72. int draw_trees = 0;
  73. int draw_ring = 1;
  74. int draw_ellipse = 1;
  75. int draw_shadows = 1;
  76.  
  77. int use_lighting = 1;
  78. int use_textures = 0;
  79. int use_normal_fog = 1;
  80. int use_fancy_fog = 0;
  81. int use_telescope = 0;
  82. int use_antialias = 0;
  83.  
  84. static void scene_identity();
  85. static void scene_project(GLfloat f = fov, float dx = 0, float dy = 0);
  86. static void scene_draw(int rend = 1);
  87. static void scene_render_telescope();
  88.  
  89. static void draw_background();
  90.  
  91. Point sun_position = {0., .707, .707, 0.};
  92. Color ambient(.25, .25, .25, 1.);
  93. static void lights_init();
  94.  
  95. static void lists_alloc();
  96. static void lists_fill();
  97.  
  98. static void ground_list_init();
  99. static void ground_draw();
  100.  
  101. Roundwall trees;
  102. static void trees_list_init();
  103. static void trees_draw();
  104.  
  105. Ring ring;
  106. static void ring_list_init();
  107. static void ring_draw();
  108.  
  109. Ellipse ellipse;
  110. static void ellipse_list_init();
  111. static void ellipse_draw();
  112.  
  113. static void shadows_list_init();
  114. static void shadows_draw();
  115.  
  116. Weather weather;
  117.  
  118. Telescope telescope;
  119. GLfloat magnif = .5;
  120. static void telescope_list_init();
  121. static void telescope_draw();
  122.  
  123. /* Read the back buffer into the accum buffer, adding in the appropriate
  124.  * alpha values */
  125. static void fog_read_image();
  126. /* Add the accum buffer to the back buffer */
  127. static void fog_write_image();
  128.  
  129.  
  130. inline float clamp(float x, float min, float max)
  131. {
  132.   if (x < min) return min;
  133.   else if (x > max) return max;
  134.   else return x;
  135. }
  136.  
  137. void scene_init() 
  138. {
  139.   scene_identity();
  140.   scene_viewer_center();
  141.  
  142.   glEnable(GL_CULL_FACE);
  143.   glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
  144.  
  145.   glEnable(GL_NORMALIZE);
  146.  
  147.   lists_alloc();
  148.  
  149.   /* Initial time will be four in the afternoon */
  150.   scene_set_time(TimeDate(16, 0));
  151.   scene_set_weather(weathers[def_weather_index]);
  152.  
  153.   lights_init();
  154.   lists_fill();
  155. }
  156.  
  157.  
  158. #if 0
  159. inline double time_minutes(int hour, int minute, int second)
  160. {
  161.   return (double)hour*60.0 + (double)minute + (double)second / 60.0;
  162. }
  163. #endif
  164.  
  165. static void scene_time_changed()
  166. {
  167.   sun_position = current_time.sun_direction();
  168.      
  169.   weather.apply(sun_position);
  170.  
  171.   lights_init();
  172.   shadows_list_init();
  173. }
  174.   
  175. void scene_set_time(TimeDate t)
  176. {
  177.   current_time = t;
  178.   scene_time_changed();
  179. }
  180.  
  181. void scene_inc_time(TimeDate t)
  182. {
  183.   current_time += t;
  184.   scene_time_changed();
  185. }
  186.  
  187. /* This is a hack -- has to be called several times to get the antialiasing
  188.  * to work */
  189. static void scene_inner_render(GLfloat dx = 0, GLfloat dy = 0)
  190. {
  191.   /* This draws layered fog if the use_fancy_fog flag is on --
  192.    * it's going to be slow on anything but high-end stuff */
  193.   if (use_fancy_fog && weather.fog_density != 0.) {
  194.     glMatrixMode(GL_PROJECTION);
  195.     glLoadIdentity();
  196.     glMatrixMode(GL_MODELVIEW);
  197.     glLoadIdentity();
  198.  
  199.     glEnable(GL_FOG);
  200.     draw_background();
  201.     scene_project(fov, dx, dy);
  202.     glClear(GL_DEPTH_BUFFER_BIT);
  203.     if (use_lighting) glEnable(GL_LIGHTING);
  204.     scene_draw();
  205.     if (use_lighting) glDisable(GL_LIGHTING);
  206.     fog_read_image();
  207.     glDisable(GL_FOG);
  208.   } else 
  209.     if (use_normal_fog && weather.fog_density != 0.) glEnable(GL_FOG);
  210.     else glDisable(GL_FOG);
  211.  
  212.   glMatrixMode(GL_PROJECTION);
  213.   glLoadIdentity();
  214.   glMatrixMode(GL_MODELVIEW);
  215.   glLoadIdentity();
  216.  
  217.   /* This is the part where we actually draw the image */
  218.   glClear(GL_DEPTH_BUFFER_BIT);
  219.   draw_background();
  220.   scene_project(fov, dx, dy);
  221.   glClear(GL_DEPTH_BUFFER_BIT);
  222.   if (use_lighting) glEnable(GL_LIGHTING);
  223.   scene_draw();
  224.   if (use_lighting) glDisable(GL_LIGHTING);
  225.  
  226.   if (use_fancy_fog && weather.fog_density != 0.) {
  227.     fog_write_image();
  228.   }
  229.  
  230.   if (use_telescope) scene_render_telescope();
  231.  
  232. }
  233.  
  234. void scene_render()
  235. {
  236.   GLint vp[4];
  237.  
  238.   scene_inner_render();
  239.   if (!use_antialias) return;
  240.  
  241.   if (use_fancy_fog) {
  242.     fprintf(stderr, "Cannot antialias while using fancy fog.\n");
  243.     return;
  244.   }
  245.  
  246.  
  247.   glGetIntegerv(GL_VIEWPORT, vp);
  248.   glAccum(GL_LOAD, .5);
  249.  
  250.   scene_inner_render(2. / (float)vp[2], 2. / (float)vp[3]);
  251.   glAccum(GL_ACCUM, .5);
  252.  
  253. /*
  254.   scene_inner_render(-2. / (float)vp[2], -2. / (float)vp[3]);
  255.   glAccum(GL_ACCUM, .25); 
  256. */
  257.   glAccum(GL_RETURN, 1);
  258.   glDrawBuffer(GL_BACK);
  259. }
  260.  
  261. static void scene_render_telescope()
  262. {
  263.   telescope.draw_setup(fov, aspect);
  264.  
  265.   /* Don't fog the telescope - moisture makes it rust.
  266.    * Seriously, it's in a strange coordinate system and fog will look
  267.    * bad on it. */
  268.   glPushAttrib(GL_ENABLE_BIT);
  269.   glDisable(GL_FOG);
  270.   if (use_textures) {
  271.     glCallList(list_texture_telescope);
  272.     glEnable(GL_TEXTURE_2D);
  273.   }
  274.   glCallList(list_telescope);
  275.   glPopAttrib();
  276.  
  277.   if (use_lighting) glEnable(GL_LIGHTING);
  278.   glEnable(GL_STENCIL_TEST);
  279.   glClearStencil(0);
  280.   glClear(GL_STENCIL_BUFFER_BIT);
  281.   glStencilFunc(GL_ALWAYS, 0x1, 0x1);
  282.   glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); 
  283.  
  284.   glDisable(GL_CULL_FACE);
  285.   telescope.draw_lens();
  286.   glEnable(GL_CULL_FACE);
  287.  
  288.   telescope.draw_takedown();
  289.  
  290.   if (use_lighting) glDisable(GL_LIGHTING);
  291.  
  292.   glStencilFunc(GL_NOTEQUAL, 0x0, 0xffffffff);
  293.   glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  294.  
  295.   scene_identity();
  296.  
  297.   draw_background();
  298.  
  299.   glMatrixMode(GL_PROJECTION);
  300.   glTranslatef(telescope.xpos / magnif, -telescope.ypos / magnif, 0);
  301.   scene_project(fov * magnif);
  302.  
  303.   glClear(GL_DEPTH_BUFFER_BIT);
  304.  
  305.   /* Pushing the lighting bit used to do really bad things, but 
  306.    * hopefully they've all gone away */
  307.   glPushAttrib(GL_LIGHTING_BIT);
  308.   lights_init();
  309.   if (use_lighting) glEnable(GL_LIGHTING);
  310.   scene_draw();
  311.   if (use_lighting) glDisable(GL_LIGHTING);
  312.   glPopAttrib();
  313.  
  314.   glDisable(GL_STENCIL_TEST);
  315. }
  316.  
  317. static void scene_identity()
  318. {
  319.   glMatrixMode(GL_PROJECTION);
  320.   glLoadIdentity();
  321.   glMatrixMode(GL_MODELVIEW);
  322.   glLoadIdentity();
  323. }
  324.  
  325. static void scene_project(GLfloat f, float dx, float dy)
  326. {
  327.   glMatrixMode(GL_PROJECTION);
  328.   glOrtho(-1 - dx, 1, -1 - dy, 1, 0, -1);
  329.   gluPerspective(f, aspect, 0.01, 40.0);
  330.   glMatrixMode(GL_MODELVIEW);
  331.   glRotatef(view_rotx, 1, 0, 0);
  332.   gluLookAt(eyep.pt[0], eyep.pt[1], eyep.pt[2], 
  333.         lookp.pt[0], lookp.pt[1], lookp.pt[2],
  334.             0, 0, 1);
  335.   glMultMatrixf(mat_view);
  336. lights_init();
  337. }
  338.  
  339. /* scene_draw() just draws the geometry - it's used for rendering and
  340.  * picking. */
  341. static void scene_draw(int rend)
  342. {
  343.   if (draw_ground) {
  344.     if (rend) {
  345.       if (use_textures) {
  346.     glCallList(list_texture_ground);
  347.     glEnable(GL_TEXTURE_2D);
  348.       } else glEnable(GL_COLOR_MATERIAL);
  349.     }
  350.     glCallList(list_ground);
  351.  
  352.     if (rend) {
  353.       glDisable(GL_TEXTURE_2D);
  354.       glDisable(GL_COLOR_MATERIAL);
  355.     }
  356.   }
  357.  
  358.   if (draw_shadows) {
  359.     if (use_textures && rend && !draw_ground) {
  360.       glCallList(list_texture_ground);
  361.       glEnable(GL_TEXTURE_2D);
  362.     }
  363.     glCallList(list_shadows);
  364.     if (use_textures && rend) glDisable(GL_TEXTURE_2D);
  365.   }
  366.  
  367.   if (draw_trees) {
  368.     if (use_textures && rend) {
  369.       glCallList(list_texture_trees);
  370.       glEnable(GL_TEXTURE_2D);
  371.     }
  372.     glCallList(list_trees);
  373.     if (use_textures && rend) glDisable(GL_TEXTURE_2D);
  374.   }
  375.  
  376.   glClear(GL_DEPTH_BUFFER_BIT);
  377.  
  378.   if (draw_ring) {
  379.     if (rend) {
  380.       if (use_textures) {
  381.     glCallList(list_texture_stones);
  382.     glEnable(GL_TEXTURE_2D);
  383.       }
  384.       glEnable(GL_COLOR_MATERIAL);
  385.       glColor3f(.5, .5, .5);
  386.     }
  387.     glCallList(list_ring);
  388.     if (rend) {
  389.       if (use_textures) glDisable(GL_TEXTURE_2D);
  390.       glDisable(GL_COLOR_MATERIAL);
  391.     }
  392.   }
  393.  
  394.   if (draw_ellipse) {
  395.     if (use_textures && rend) {
  396.       // Hack to avoid doing something expensive twice in a row
  397.       if (!draw_ring) glCallList(list_texture_stones);
  398.       glEnable(GL_TEXTURE_2D);
  399.     }
  400.     glCallList(list_ellipse);
  401.     if (use_textures && rend) glDisable(GL_TEXTURE_2D);
  402.   }
  403. }
  404.  
  405. static void draw_background()
  406. {
  407.   weather.draw_sky(sun_position);
  408. }
  409.  
  410. void scene_viewer_center()
  411. {
  412.   glPushMatrix();
  413.   glLoadIdentity();
  414.   glGetFloatv(GL_MODELVIEW_MATRIX, mat_view);
  415.   glPopMatrix();
  416.   view_rotx = 0;
  417. }
  418.  
  419. void scene_viewer_rotate_worldz(GLfloat degrees)
  420. {
  421.   glMatrixMode(GL_MODELVIEW);
  422.   glPushMatrix();
  423.   glLoadIdentity();
  424.   glRotatef(degrees, 0, 0, 1);
  425.   glMultMatrixf(mat_view);
  426.   glGetFloatv(GL_MODELVIEW_MATRIX, mat_view);
  427.   glPopMatrix();
  428.   glMatrixMode(GL_MODELVIEW);
  429. }
  430.  
  431. void scene_viewer_rotatez(GLfloat degrees)
  432. {
  433.   glMatrixMode(GL_PROJECTION);
  434.   glPushMatrix();
  435.   glLoadIdentity();
  436.   glRotatef(degrees, 0, 0, 1);
  437.   glMultMatrixf(mat_view);
  438.   glGetFloatv(GL_PROJECTION_MATRIX, mat_view);
  439.   glPopMatrix();
  440.   glMatrixMode(GL_MODELVIEW);
  441. }
  442.  
  443. void scene_viewer_rotatex(GLfloat degrees)
  444. {
  445.   view_rotx += degrees;
  446.   view_rotx = clamp(view_rotx, -60, 60);
  447.   scene_identity();
  448.   scene_project();
  449.   lights_init();
  450. }
  451.  
  452. void scene_viewer_translate(GLfloat dist)
  453. {
  454.   glMatrixMode(GL_PROJECTION);
  455.   glPushMatrix();
  456.   glLoadIdentity();
  457.   glTranslatef(0, dist, 0);
  458.   glMultMatrixf(mat_view);
  459.   glGetFloatv(GL_PROJECTION_MATRIX, mat_view);
  460.   glPopMatrix();
  461.   glMatrixMode(GL_MODELVIEW);
  462.   scene_identity();
  463.   scene_project();
  464.   lights_init();
  465. }
  466.  
  467. void scene_position_telescope(GLfloat x, GLfloat y)
  468. {
  469.   telescope.xpos = x;
  470.   telescope.ypos = y;
  471. }
  472.  
  473. void scene_get_position_telescope(GLfloat *x, GLfloat *y)
  474. {
  475.   *x = telescope.xpos;
  476.   *y = telescope.ypos;
  477. }
  478.  
  479. void scene_get_radius_telescope(GLfloat *r)
  480. {
  481.   *r = telescope.get_radius();
  482. }
  483.  
  484. void scene_set_weather(Weather w)
  485. {
  486.   weather = w;
  487.   weather.apply(sun_position);
  488.   shadows_list_init();
  489. }
  490.  
  491. static int get_lists(int size)
  492. {
  493.   int i;
  494.   i = glGenLists(size);
  495.   if (size && !i) {
  496.     fprintf(stderr, "Unable to allocate %d display lists.\n");
  497.     exit(1);
  498.   }
  499.   return i;
  500. }
  501.  
  502. static void lights_init()
  503. {
  504.   glLightfv(GL_LIGHT0, GL_POSITION, sun_position.pt);
  505.  
  506.   /* This light gives a diffuse coefficient when the sun is off - 
  507.    * it's used for drawing shadows */
  508.   glLightfv(GL_LIGHT1, GL_AMBIENT, black.c);
  509.   glLightfv(GL_LIGHT1, GL_DIFFUSE, black.c);
  510.   glLightfv(GL_LIGHT1, GL_SPECULAR, black.c);
  511. }
  512.  
  513. static void textures_list_init()
  514. {
  515.   RGBImageRec *teximage = NULL;
  516.   
  517.   teximage = rgbImageLoad((char *)texfile_stones);
  518.   if (!teximage) {
  519.       fprintf(stderr, "Error: cannot load texture %s\n", texfile_stones);
  520.       exit(1);
  521.   }
  522.   glNewList(list_texture_stones, GL_COMPILE);
  523.   gluBuild2DMipmaps(GL_TEXTURE_2D, 3, teximage->sizeX, teximage->sizeY, 
  524.             GL_RGB, GL_UNSIGNED_BYTE, teximage->data);
  525.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
  526.          GL_NEAREST_MIPMAP_NEAREST);
  527.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
  528.          GL_LINEAR);
  529.   glMatrixMode(GL_TEXTURE);
  530.   glLoadIdentity();
  531.   glMatrixMode(GL_MODELVIEW);
  532.   glDisable(GL_TEXTURE_GEN_S);
  533.   glDisable(GL_TEXTURE_GEN_T);
  534.   glEndList();
  535.   rgbImageFree(teximage);
  536.  
  537.   teximage = rgbImageLoad((char *)texfile_ground);
  538.   if (!teximage) {
  539.       fprintf(stderr, "Error: cannot load texture %s\n", texfile_ground);
  540.       exit(1);
  541.   }
  542.   glNewList(list_texture_ground, GL_COMPILE);
  543.   gluBuild2DMipmaps(GL_TEXTURE_2D, 3, teximage->sizeX, teximage->sizeY, 
  544.             GL_RGB, GL_UNSIGNED_BYTE, teximage->data);
  545.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
  546.           GL_NEAREST_MIPMAP_NEAREST);
  547.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
  548.           GL_LINEAR);
  549.   glMatrixMode(GL_TEXTURE);
  550.   glLoadIdentity();
  551.   glScalef(100, 100, 1);
  552.   glMatrixMode(GL_MODELVIEW);
  553.   glDisable(GL_TEXTURE_GEN_S);
  554.   glDisable(GL_TEXTURE_GEN_T);
  555.   glEndList();
  556.   rgbImageFree(teximage);
  557.  
  558.   /* Figure out some way to get an alpha component out of the tk --
  559.    * otherwise we're really hosed */
  560.   teximage = rgbImageLoad((char *)texfile_trees);
  561.   if (!teximage) {
  562.       fprintf(stderr, "Error: cannot load texture %s\n", texfile_trees);
  563.       exit(1);
  564.   }
  565.   glNewList(list_texture_trees, GL_COMPILE);
  566.   /* In the final scenerio we probably won't want to mipmap this, but it's
  567.    * not square and I don't feel like bothering to scale it */
  568.   gluBuild2DMipmaps(GL_TEXTURE_2D, 3, teximage->sizeX, teximage->sizeY,
  569.             GL_RGB, GL_UNSIGNED_BYTE, teximage->data);
  570.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
  571.           GL_NEAREST_MIPMAP_NEAREST);
  572.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
  573.           GL_LINEAR);
  574.   glMatrixMode(GL_TEXTURE);
  575.   glLoadIdentity();
  576.   glMatrixMode(GL_MODELVIEW);
  577.   glDisable(GL_TEXTURE_GEN_S);
  578.   glDisable(GL_TEXTURE_GEN_T);
  579.   glEndList();
  580.   rgbImageFree(teximage);
  581.  
  582.   teximage = rgbImageLoad((char *)texfile_telescope);
  583.   if (!teximage) {
  584.       fprintf(stderr, "Error: cannot load texture %s\n", texfile_telescope);
  585.       exit(1);
  586.   }
  587.   glNewList(list_texture_telescope, GL_COMPILE);
  588.   glTexImage2D(GL_TEXTURE_2D, 0, 3, teximage->sizeX, teximage->sizeY,
  589.            0, GL_RGB, GL_UNSIGNED_BYTE, teximage->data);
  590.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  591.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  592.   glMatrixMode(GL_TEXTURE);
  593.   glLoadIdentity();
  594.   glMatrixMode(GL_MODELVIEW);
  595.   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  596.   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  597.   glEnable(GL_TEXTURE_GEN_S);
  598.   glEnable(GL_TEXTURE_GEN_T);
  599.   glEndList();
  600.   rgbImageFree(teximage);
  601. }
  602.  
  603. static void lists_alloc()
  604. {
  605.   list_ground = get_lists(1);
  606.   list_texture_ground = get_lists(1);
  607.   list_trees = get_lists(1);
  608.   list_texture_trees = get_lists(1);
  609.   list_ring = get_lists(1);
  610.   list_ellipse = get_lists(1);
  611.   list_texture_stones = get_lists(1);
  612.   list_shadows = get_lists(1);
  613.   list_telescope = get_lists(1);
  614.   list_texture_telescope = get_lists(1);
  615. }
  616.  
  617. static void lists_fill() {
  618.   ground_list_init();
  619.   trees_list_init();
  620.   shadows_list_init();
  621.   ring_list_init();
  622.   ellipse_list_init();
  623.   textures_list_init();
  624.   telescope_list_init();
  625. }
  626.  
  627. static void ground_list_init()
  628. {
  629.   glNewList(list_ground, GL_COMPILE);
  630.   ground_draw();
  631.   glEndList();
  632. }
  633.  
  634. static void ground_draw() 
  635. {
  636.   glColor3f(0, .75, 0);
  637.  
  638.   glLoadName(name_ground);
  639.  
  640.   glNormal3f(0, 0, 1);
  641.  
  642.   glPushMatrix();
  643.   /* Making something this big would confuse the zbuffer, but we're 
  644.    * clearing that AFTER drawing this, so it's ok */
  645.   glScalef(100, 100, 1);
  646.   glBegin(GL_QUADS);
  647.   glTexCoord2f(0, 0);
  648.   glVertex2f(-1, -1);
  649.   glTexCoord2f(1, 0);
  650.   glVertex2f(1, -1);
  651.   glTexCoord2f(1, 1);
  652.   glVertex2f(1, 1);
  653.   glTexCoord2f(0, 1);
  654.   glVertex2f(-1, 1);
  655.   glEnd();
  656.   glPopMatrix();
  657. }
  658.  
  659. static void trees_list_init()
  660. {
  661.   glNewList(list_trees, GL_COMPILE);
  662.   trees_draw();
  663.   glEndList();
  664. }
  665.  
  666. static void trees_draw()
  667. {
  668.   glEnable(GL_COLOR_MATERIAL);
  669.   glColor3f(0, .5, 0);
  670.  
  671.   glLoadName(name_trees);
  672.   
  673.   glEnable(GL_BLEND);
  674.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  675.   trees.draw();
  676.   glDisable(GL_BLEND);
  677.  
  678.   glDisable(GL_COLOR_MATERIAL);
  679. }
  680.  
  681. static void ring_list_init()
  682. {
  683.   glNewList(list_ring, GL_COMPILE);
  684.   ring_draw();
  685.   glEndList();
  686. }
  687.  
  688. static void ring_draw()
  689. {
  690.   glLoadName(name_ring);
  691.  
  692.   glEnable(GL_DEPTH_TEST);
  693.   ring.erode(.1);
  694.   ring.draw();
  695.   glDisable(GL_DEPTH_TEST);
  696. }
  697.  
  698. static void ellipse_list_init()
  699. {
  700.   glNewList(list_ellipse, GL_COMPILE);
  701.   ellipse_draw();
  702.   glEndList();
  703. }
  704.  
  705. static void ellipse_draw()
  706. {
  707.   glEnable(GL_COLOR_MATERIAL);
  708.   glColor3f(.5, .5, .5);
  709.   
  710.   glEnable(GL_DEPTH_TEST);
  711.  
  712.   glLoadName(name_ellipse);
  713.  
  714.   ellipse.erode(.1);
  715.   ellipse.draw();
  716.  
  717.   glDisable(GL_DEPTH_TEST);
  718.  
  719.   glDisable(GL_COLOR_MATERIAL);
  720. }
  721.  
  722. static void shadows_list_init()
  723. {
  724.   glNewList(list_shadows, GL_COMPILE);
  725.   shadows_draw();
  726.   glEndList();
  727. }
  728.  
  729. static void shadows_draw()
  730. {
  731.   Color grass(0, .75, 0);
  732.  
  733.   glPushAttrib(GL_ENABLE_BIT);
  734.  
  735.   /* Turn the sun off */
  736.   glDisable(GL_LIGHT0);
  737.   glEnable(GL_LIGHT1);
  738.   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, grass.c);
  739.   glColor3fv((grass * .5).c);
  740.  
  741.   glDisable(GL_CULL_FACE);
  742.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  743.   glEnable(GL_BLEND);
  744.   ring.draw_shadow(sun_position, weather.shadow_blur(), 
  745.            grass * .5, grass);
  746.   ellipse.draw_shadow(sun_position, weather.shadow_blur(), 
  747.               grass * .5, grass);
  748.   glPopAttrib();
  749. }
  750.  
  751. static void telescope_list_init()
  752. {
  753.   glNewList(list_telescope, GL_COMPILE);
  754.   telescope_draw();
  755.   glEndList();
  756. }
  757.  
  758. static void telescope_draw()
  759. {
  760.   glLoadName(name_telescope);
  761.   glEnable(GL_COLOR_MATERIAL);
  762.   glDisable(GL_CULL_FACE);
  763.   glClear(GL_DEPTH_BUFFER_BIT);
  764.   glEnable(GL_DEPTH_TEST);
  765.   telescope.draw_body();
  766.   glDisable(GL_DEPTH_TEST);
  767.   glEnable(GL_CULL_FACE);
  768.   glDisable(GL_COLOR_MATERIAL);
  769. }
  770.  
  771. static void fog_read_image()
  772. {
  773.   glPushMatrix();
  774.   glLoadIdentity();
  775.  
  776.   /* This creates an alpha gradient across the image */
  777. /*  glColorMask(0, 0, 0, 1);
  778.   glBegin(GL_QUADS);
  779.   glColor4f(1, 1, 1, 1);
  780.   glVertex2f(-1, -1);
  781.   glVertex2f(1, -1);
  782.   glColor4f(1, 1, 1, 0);
  783.   glVertex2f(1, 1);
  784.   glVertex2f(-1, 1);
  785.   glEnd();
  786.   glColorMask(1, 1, 1, 1);
  787. */
  788.   glDrawBuffer(GL_BACK);
  789.   glReadBuffer(GL_BACK);
  790.   glAccum(GL_LOAD, 1);
  791.  
  792.   glPopMatrix();
  793. }
  794.  
  795. static void fog_write_image()
  796. {
  797.   glDrawBuffer(GL_BACK);
  798.  
  799.   /* Put this back in once we're done testing */
  800. //  glEnable(GL_BLEND);
  801.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  802.   glAccum(GL_RETURN, 1);  
  803.   glDisable(GL_BLEND);
  804. }
  805.